package Test1.GeneralFunction;

import Test1.HCNetSDK;
import com.sun.jna.Pointer;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class FMSGCallBack_V31 implements HCNetSDK.FMSGCallBack_V31 {
    //报警信息回调函数

    public boolean invoke(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) throws UnsupportedEncodingException {
        List<String[]> reList = AlarmDataHandle(lCommand, pAlarmer, pAlarmInfo, dwBufLen, pUser);
        for (int i = 0; i < reList.size(); i++) {
            for (int j = 0; j < 3; j++) {
                System.out.println(reList.get(i)[j]);
            }
        }
        return true;
    }

    /**
     * 报警信息回调函数实现
     *
     * @param lCommand   上传的消息类型，不同的报警信息对应不同的类型，通过类型区分是什么报警信息
     * @param pAlarmer   报警设备信息，包括设备序列号、IP地址、登录IUserID句柄等
     * @param pAlarmInfo 报警信息，通过lCommand值判断pAlarmer对应的结构体
     * @param dwBufLen   报警信息缓存大小
     * @param pUser      用户数据
     * @return 报警信息集合
     */
    public List<String[]> AlarmDataHandle(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) throws UnsupportedEncodingException {
        System.out.println("lCommand = 0x" + Integer.toHexString(lCommand));
        // alarmList 为报警信息集合
        List<String[]> alarmList = new ArrayList<>();
        String[] newRow = new String[3];

        //报警时间
        Date today = new Date();
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String[] sIP;

        String sAlarmType = "lCommand = 0x" + Integer.toHexString(lCommand);
        //lCommand是传的报警类型
        switch (lCommand) {
            //温度报警
            case HCNetSDK.COMM_THERMOMETRY_ALARM:
                HCNetSDK.NET_DVR_THERMOMETRY_ALARM struTherAlarm = new HCNetSDK.NET_DVR_THERMOMETRY_ALARM();
                struTherAlarm.dwSize = struTherAlarm.size();
                struTherAlarm.write();
                Pointer pTher = struTherAlarm.getPointer();
                pTher.write(0,pAlarmInfo.getByteArray(0,struTherAlarm.size()),0,struTherAlarm.size());
                struTherAlarm.read();
                System.out.println("报警类型："+ struTherAlarm.byAlarmType + ",规则类型" + struTherAlarm.byRuleCalibType +
                        "，当前温度：" + struTherAlarm.fCurrTemperature + ",配置规则温度：" + struTherAlarm.fRuleTemperature);
                newRow[0] = dateFormat.format(today);
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                alarmList.add(newRow);

                if(struTherAlarm.dwPicLen > 0) {
                    SimpleDateFormat sf0 = new SimpleDateFormat("yyyyMMddHHmmss");
                    String newName1 = sf0.format(new Date());
                    FileOutputStream fout0;
                    FileOutputStream fout1;
                    try {
                        fout0 = new FileOutputStream(".\\pic\\" + new String(pAlarmer.sDeviceIP).trim()
                                + "wEventTypeEx[TMA]_" + newName1 + "_Vis.jpg");
                        fout1 = new FileOutputStream(".\\pic\\" + new String(pAlarmer.sDeviceIP).trim()
                                + "wEventTypeEx[TMA]_" + newName1 + "_Ther.jpg");
                        //将字节写入文件
                        long offset = 0;
                        ByteBuffer buffers = struTherAlarm.pPicBuff.getByteBuffer(offset, struTherAlarm.dwPicLen);
                        ByteBuffer buffers1 = struTherAlarm.pThermalPicBuff.getByteBuffer(offset, struTherAlarm.dwThermalPicLen);

                        byte[] bytes = new byte[struTherAlarm.dwPicLen];
                        byte[] bytes1 = new byte[struTherAlarm.dwThermalPicLen];
                        buffers.rewind();
                        buffers1.rewind();
                        buffers.get(bytes);
                        buffers1.get(bytes1);
                        fout0.write(bytes);
                        fout1.write(bytes1);
                        fout0.close();
                        fout1.close();
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                break;

            //火点报警
            case HCNetSDK.COMM_FIREDETECTION_ALARM:
                HCNetSDK.NET_DVR_FIREDETECTION_ALARM struFireAlarm = new HCNetSDK.NET_DVR_FIREDETECTION_ALARM();
              //  struFireAlarm.dwSize = struFireAlarm.size();
                struFireAlarm.write();
                Pointer pFire = struFireAlarm.getPointer();
                pFire.write(0,pAlarmInfo.getByteArray(0,struFireAlarm.size()),0,struFireAlarm.size());
                struFireAlarm.read();
                System.out.println("报警通道号："+ struFireAlarm.struDevInfo.byChannel+ "报警子类型："+ struFireAlarm.byAlarmSubType + ",火点最高温度" + struFireAlarm.wFireMaxTemperature +
                        "，火点目标距离：" + struFireAlarm.wTargetDistance + ",策略类型：" + struFireAlarm.byStrategyType);
                newRow[0] = dateFormat.format(today);
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                alarmList.add(newRow);

                if(struFireAlarm.dwVisiblePicLen  > 0) {
                    SimpleDateFormat sf0 = new SimpleDateFormat("yyyyMMddHHmmss");
                    String newName1 = sf0.format(new Date());
                    FileOutputStream fout0;
                    FileOutputStream fout1;
                    try {
                        fout0 = new FileOutputStream(".\\pic\\" + new String(pAlarmer.sDeviceIP).trim()
                                + "wEventTypeEx[FDA]_" + newName1 + "_Vis.jpg");
                        fout1 = new FileOutputStream(".\\pic\\" + new String(pAlarmer.sDeviceIP).trim()
                                + "wEventTypeEx[FDA]_" + newName1 + "_Ther.jpg");
                        //将字节写入文件
                        long offset = 0;
                        ByteBuffer buffers = struFireAlarm.pVisiblePicBuf.getByteBuffer(offset, struFireAlarm.dwVisiblePicLen);
                        ByteBuffer buffers1 = struFireAlarm.pBuffer.getByteBuffer(offset, struFireAlarm.dwPicDataLen);

                        byte[] bytes = new byte[struFireAlarm.dwVisiblePicLen];
                        byte[] bytes1 = new byte[struFireAlarm.dwPicDataLen];
                        buffers.rewind();
                        buffers1.rewind();
                        buffers.get(bytes);
                        buffers1.get(bytes1);
                        fout0.write(bytes);
                        fout1.write(bytes1);
                        fout0.close();
                        fout1.close();
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                break;

            // 行为分析信息上传
            case HCNetSDK.COMM_ALARM_RULE:
                HCNetSDK.NET_VCA_RULE_ALARM strVcaAlarm = new HCNetSDK.NET_VCA_RULE_ALARM();
                strVcaAlarm.write();
                Pointer pVcaInfo = strVcaAlarm.getPointer();
                pVcaInfo.write(0, pAlarmInfo.getByteArray(0, strVcaAlarm.size()), 0, strVcaAlarm.size());
                strVcaAlarm.read();

                switch (strVcaAlarm.struRuleInfo.wEventTypeEx) {
                    case 1:
                        sAlarmType = sAlarmType + new String("：穿越警戒面") + "，" +
                                "_wPort:" + strVcaAlarm.struDevInfo.wPort +
                                "_byChannel:" + strVcaAlarm.struDevInfo.byChannel +
                                "_byIvmsChannel:" + strVcaAlarm.struDevInfo.byIvmsChannel +
                                "_Dev IP：" + new String(strVcaAlarm.struDevInfo.struDevIP.sIpV4);
                        break;
                    case 2:
                        sAlarmType = sAlarmType + new String("：目标进入区域") + "，" +
                                "_wPort:" + strVcaAlarm.struDevInfo.wPort +
                                "_byChannel:" + strVcaAlarm.struDevInfo.byChannel +
                                "_byIvmsChannel:" + strVcaAlarm.struDevInfo.byIvmsChannel +
                                "_Dev IP：" + new String(strVcaAlarm.struDevInfo.struDevIP.sIpV4);
                        break;
                    case 3:
                        sAlarmType = sAlarmType + new String("：目标离开区域") + "，" +
                                "_wPort:" + strVcaAlarm.struDevInfo.wPort +
                                "_byChannel:" + strVcaAlarm.struDevInfo.byChannel +
                                "_byIvmsChannel:" + strVcaAlarm.struDevInfo.byIvmsChannel +
                                "_Dev IP：" + new String(strVcaAlarm.struDevInfo.struDevIP.sIpV4);
                        break;
                    default:
                        sAlarmType = sAlarmType + new String("：其他行为分析报警，事件类型：")
                                + strVcaAlarm.struRuleInfo.wEventTypeEx +
                                "_wPort:" + strVcaAlarm.struDevInfo.wPort +
                                ", _byChannel:" + strVcaAlarm.struDevInfo.byChannel +
                                " ,_byIvmsChannel:" + strVcaAlarm.struDevInfo.byIvmsChannel +
                                ", _Dev IP：" + new String(strVcaAlarm.struDevInfo.struDevIP.sIpV4);
                        break;
                }
                newRow[0] = dateFormat.format(today);
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                alarmList.add(newRow);

                if (strVcaAlarm.dwPicDataLen > 0) {
                    SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
                    String newName = sf.format(new Date());
                    FileOutputStream fout;
                    try {
                        fout = new FileOutputStream(".\\pic\\" + new String(pAlarmer.sDeviceIP).trim()
                                + "wEventTypeEx[" + strVcaAlarm.struRuleInfo.wEventTypeEx + "]_" + newName + "_vca.jpg");
                        //将字节写入文件
                        long offset = 0;
                        ByteBuffer buffers = strVcaAlarm.pImage.getByteBuffer(offset, strVcaAlarm.dwPicDataLen);
                        byte[] bytes = new byte[strVcaAlarm.dwPicDataLen];
                        buffers.rewind();
                        buffers.get(bytes);
                        fout.write(bytes);
                        fout.close();
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                break;

            //人脸识别结果上传
            case HCNetSDK.COMM_UPLOAD_FACESNAP_RESULT:
                //实时人脸抓拍上传
                HCNetSDK.NET_VCA_FACESNAP_RESULT strFaceSnapInfo = new HCNetSDK.NET_VCA_FACESNAP_RESULT();
                strFaceSnapInfo.write();
                Pointer pFaceSnapInfo = strFaceSnapInfo.getPointer();
                pFaceSnapInfo.write(0, pAlarmInfo.getByteArray(0, strFaceSnapInfo.size()), 0, strFaceSnapInfo.size());
                strFaceSnapInfo.read();
                sAlarmType = sAlarmType + "：人脸抓拍上传，人脸评分：" + strFaceSnapInfo.dwFaceScore + "，年龄段：" + strFaceSnapInfo.struFeature.byAgeGroup + "，性别：" + strFaceSnapInfo.struFeature.bySex;
                newRow[0] = dateFormat.format(today);
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(strFaceSnapInfo.struDevInfo.struDevIP.sIpV4).split("\0", 2);
                newRow[2] = sIP[0];
                alarmList.add(newRow);
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //设置日期格式
                String time = df.format(new Date()); // new Date()为获取当前系统时间
                //人脸图片写文件
                try {
                    FileOutputStream small = new FileOutputStream(System.getProperty("user.dir") + "\\pic\\" + time + "small.jpg");
                    FileOutputStream big = new FileOutputStream(System.getProperty("user.dir") + "\\pic\\" + time + "big.jpg");

                    if (strFaceSnapInfo.dwFacePicLen > 0) {

                        try {
                            small.write(strFaceSnapInfo.pBuffer1.getByteArray(0, strFaceSnapInfo.dwFacePicLen), 0, strFaceSnapInfo.dwFacePicLen);
                            small.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (strFaceSnapInfo.dwFacePicLen > 0) {
                        try {
                            big.write(strFaceSnapInfo.pBuffer2.getByteArray(0, strFaceSnapInfo.dwBackgroundPicLen), 0, strFaceSnapInfo.dwBackgroundPicLen);
                            big.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                } catch (FileNotFoundException ex) {
                    ex.printStackTrace();
                }
                break;

            //设备支持AI开放平台接入，上传视频检测数据
            case HCNetSDK.COMM_UPLOAD_AIOP_VIDEO:
                HCNetSDK.NET_AIOP_VIDEO_HEAD struAIOPVideo = new HCNetSDK.NET_AIOP_VIDEO_HEAD();
                struAIOPVideo.write();
                Pointer pAIOPVideo = struAIOPVideo.getPointer();
                pAIOPVideo.write(0, pAlarmInfo.getByteArray(0, struAIOPVideo.size()), 0, struAIOPVideo.size());
                struAIOPVideo.read();

                String strTime = "" + String.format("%04d", struAIOPVideo.struTime.wYear) +
                        String.format("%02d", struAIOPVideo.struTime.wMonth) +
                        String.format("%02d", struAIOPVideo.struTime.wDay) +
                        String.format("%02d", struAIOPVideo.struTime.wHour) +
                        String.format("%02d", struAIOPVideo.struTime.wMinute) +
                        String.format("%02d", struAIOPVideo.struTime.wSecond) +
                        String.format("%03d", struAIOPVideo.struTime.wMilliSec);

                sAlarmType = sAlarmType + "：AI开放平台接入，上传视频检测数据，通道号:" + struAIOPVideo.dwChannel +
                        ", 时间:" + strTime;

                newRow[0] = dateFormat.format(today);
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                alarmList.add(newRow);

                if (struAIOPVideo.dwAIOPDataSize > 0) {
                    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String newName = sf.format(new Date());
                    FileOutputStream fout;
                    try {
                        String filename = ".\\pic\\" + new String(pAlarmer.sDeviceIP).trim() +
                                "_" + newName + "_AIO_VideoData.json";
                        fout = new FileOutputStream(filename);
                        //将字节写入文件
                        long offset = 0;
                        ByteBuffer buffers = struAIOPVideo.pBufferAIOPData.getByteBuffer(offset, struAIOPVideo.dwAIOPDataSize);
                        byte[] bytes = new byte[struAIOPVideo.dwAIOPDataSize];
                        buffers.rewind();
                        buffers.get(bytes);
                        fout.write(bytes);
                        fout.close();
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if (struAIOPVideo.dwPictureSize > 0) {
                    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String newName = sf.format(new Date());
                    FileOutputStream fout;
                    try {
                        String filename = ".\\pic\\" + new String(pAlarmer.sDeviceIP).trim() +
                                "_" + newName + "_AIO_VideoPic.jpg";
                        fout = new FileOutputStream(filename);
                        //将字节写入文件
                        long offset = 0;
                        ByteBuffer buffers = struAIOPVideo.pBufferPicture.getByteBuffer(offset, struAIOPVideo.dwPictureSize);
                        byte[] bytes = new byte[struAIOPVideo.dwPictureSize];
                        buffers.rewind();
                        buffers.get(bytes);
                        fout.write(bytes);
                        fout.close();
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                break;
            //设备支持AI开放平台接入，上传视频检测数据
            case HCNetSDK.COMM_UPLOAD_AIOP_PICTURE:
                HCNetSDK.NET_AIOP_PICTURE_HEAD struAIOPPic = new HCNetSDK.NET_AIOP_PICTURE_HEAD();
                struAIOPPic.write();
                Pointer pAIOPPic = struAIOPPic.getPointer();
                pAIOPPic.write(0, pAlarmInfo.getByteArray(0, struAIOPPic.size()), 0, struAIOPPic.size());
                struAIOPPic.read();

                String strPicTime = "" + String.format("%04d", struAIOPPic.struTime.wYear) +
                        String.format("%02d", struAIOPPic.struTime.wMonth) +
                        String.format("%02d", struAIOPPic.struTime.wDay) +
                        String.format("%02d", struAIOPPic.struTime.wHour) +
                        String.format("%02d", struAIOPPic.struTime.wMinute) +
                        String.format("%02d", struAIOPPic.struTime.wSecond) +
                        String.format("%03d", struAIOPPic.struTime.wMilliSec);

                sAlarmType = sAlarmType + "：AI开放平台接入，上传图片检测数据，通道号:" + new String(struAIOPPic.szPID) +
                        ", 时间:" + strPicTime;

                newRow[0] = dateFormat.format(today);
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                alarmList.add(newRow);

                if (struAIOPPic.dwAIOPDataSize > 0) {
                    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String newName = sf.format(new Date());
                    FileOutputStream fout;
                    try {
                        String filename = ".\\pic\\" + new String(pAlarmer.sDeviceIP).trim() +
                                "_" + newName + "_AIO_PicData.json";
                        fout = new FileOutputStream(filename);
                        //将字节写入文件
                        long offset = 0;
                        ByteBuffer buffers = struAIOPPic.pBufferAIOPData.getByteBuffer(offset, struAIOPPic.dwAIOPDataSize);
                        byte[] bytes = new byte[struAIOPPic.dwAIOPDataSize];
                        buffers.rewind();
                        buffers.get(bytes);
                        fout.write(bytes);
                        fout.close();
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                break;
            //ISAPI协议报警信息
            case HCNetSDK.COMM_ISAPI_ALARM:
                HCNetSDK.NET_DVR_ALARM_ISAPI_INFO struEventISAPI = new HCNetSDK.NET_DVR_ALARM_ISAPI_INFO();
                struEventISAPI.write();
                Pointer pEventISAPI = struEventISAPI.getPointer();
                pEventISAPI.write(0, pAlarmInfo.getByteArray(0, struEventISAPI.size()), 0, struEventISAPI.size());
                struEventISAPI.read();

                sAlarmType = sAlarmType + "：ISAPI协议报警信息, 数据格式:" + struEventISAPI.byDataType +
                        ", 图片个数:" + struEventISAPI.byPicturesNumber;

                newRow[0] = dateFormat.format(today);
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                alarmList.add(newRow);

                SimpleDateFormat sf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String curTime = sf1.format(new Date());
                FileOutputStream foutdata;
                try {
                    String jsonfilename = ".\\pic\\" + new String(pAlarmer.sDeviceIP).trim() + curTime + "_ISAPI_Alarm_" + ".json";
                    foutdata = new FileOutputStream(jsonfilename);
                    //将字节写入文件
                    ByteBuffer jsonbuffers = struEventISAPI.pAlarmData.getByteBuffer(0, struEventISAPI.dwAlarmDataLen);
                    byte[] jsonbytes = new byte[struEventISAPI.dwAlarmDataLen];
                    jsonbuffers.rewind();
                    jsonbuffers.get(jsonbytes);
                    foutdata.write(jsonbytes);
                    foutdata.close();
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                for (int i = 0; i < struEventISAPI.byPicturesNumber; i++) {
                    HCNetSDK.NET_DVR_ALARM_ISAPI_PICDATA struPicData = new HCNetSDK.NET_DVR_ALARM_ISAPI_PICDATA();
                    struPicData.write();
                    Pointer pPicData = struPicData.getPointer();
                    pPicData.write(0, struEventISAPI.pPicPackData.getByteArray(i * struPicData.size(), struPicData.size()), 0, struPicData.size());
                    struPicData.read();

                    FileOutputStream fout;
                    try {
                        String filename = ".\\pic\\" + new String(pAlarmer.sDeviceIP).trim() + curTime +
                                "_ISAPIPic_" + i + "_" + new String(struPicData.szFilename).trim() + ".jpg";
                        fout = new FileOutputStream(filename);
                        //将字节写入文件
                        long offset = 0;
                        ByteBuffer buffers = struPicData.pPicData.getByteBuffer(offset, struPicData.dwPicLen);
                        byte[] bytes = new byte[struPicData.dwPicLen];
                        buffers.rewind();
                        buffers.get(bytes);
                        fout.write(bytes);
                        fout.close();
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                break;
            default:
                newRow[0] = dateFormat.format(today);
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                alarmList.add(newRow);
                break;
        }
        return alarmList;
    }
}
